package com.crocodileq.consultant.config;


import com.crocodileq.consultant.aiService.ConsultantService;
import com.crocodileq.consultant.repository.RedisChatMemoryStore;
import dev.langchain4j.community.store.embedding.redis.RedisEmbeddingStore;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.document.loader.ClassPathDocumentLoader;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/***
 * @Author 鳄鱼杆
 * @Date 2025/9/3 16:33
 */
@Configuration
public class CommonConfig {

    @Autowired
    private OpenAiChatModel model;

    @Autowired
    private RedisChatMemoryStore redisChatMemoryStore;

    @Autowired
    private EmbeddingModel embeddingModel;

    @Autowired
    private RedisEmbeddingStore redisEmbeddingStore;

    //@AiService代替配置类创建AiService代理类
    public ConsultantService consultantService(){
        ConsultantService consultantService = AiServices.builder(ConsultantService.class)
                .chatModel(model)
                .build();

        return consultantService;
    }

    @Bean //会话记忆对象
    public ChatMemory chatMemory(){
        return MessageWindowChatMemory.builder()
                .maxMessages(20)
                .build();
    }

    //会话记忆对象提供者
    @Bean
    public ChatMemoryProvider chatMemoryProvider(){
        ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
            @Override
            public ChatMemory get(Object memoryId) {
                return MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .chatMemoryStore(redisChatMemoryStore)
                        .maxMessages(20)
                        .build();
            }
        };

        return chatMemoryProvider;
    }

    //构建向量数据库操作对象
    @Bean
    public EmbeddingStore store(){
        //加载知识数据文档
        List<Document> documents = ClassPathDocumentLoader.loadDocuments("content");
        //构建向量数据库操作对象
//        InMemoryEmbeddingStore store = new InMemoryEmbeddingStore();
        //构建DocumentSplitter对象
        DocumentSplitter recursive = DocumentSplitters.recursive(500, 100);
        // 构建EmbeddingStore Ingestor对象，完成文本数据的切割、向量化、存储
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .embeddingStore(redisEmbeddingStore) //向量数据库操作对象
                .documentSplitter(recursive)
                .embeddingModel(embeddingModel)
                .build();
        ingestor.ingest(documents);

        return redisEmbeddingStore;

    }

    //构建向量数据库检索对象
    @Bean
    public ContentRetriever contentRetriever( /*@Qualifier("store") EmbeddingStore store */){
        return EmbeddingStoreContentRetriever.builder()
                .embeddingStore(redisEmbeddingStore) //向量数据库操作对象
                .embeddingModel(embeddingModel)
                .minScore(0.6) //余弦距离阈值
                .maxResults(3) //最大返回结果数量
                .build();
    }

}
